package com.xb.loan.cashier.biz.task.alipay;

import com.xb.loan.cashier.biz.dao.bean.CashierEncashBatch;
import com.xb.loan.cashier.biz.dao.bean.CashierEncashOrder;
import com.xb.loan.cashier.biz.dao.bean.CashierPayChannel;
import com.xb.loan.cashier.biz.dao.bean.CashierPayChannelBank;
import com.xb.loan.cashier.biz.pay.alipay.AlipayPayment;
import com.xb.loan.cashier.biz.service.CashierEncashBatchService;
import com.xb.loan.cashier.biz.service.CashierEncashOrderService;
import com.xb.loan.cashier.biz.service.CashierPayChannelBankService;
import com.xb.loan.cashier.biz.service.CashierPayChannelService;
import com.xb.loan.cashier.biz.task.ThirdEncashTask;
import com.xb.loan.cashier.biz.util.Configure;
import com.xb.loan.cashier.service.constant.ICashierEnumConst;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 支付宝提现任务
 */
@Component(value="alipayWapEncashTask")
@Scope(value="prototype")
public class AlipayWapEncashTask extends ThirdEncashTask {

    private static Logger loggger = LoggerFactory.getLogger(AlipayWapEncashTask.class);
    @Autowired
    private CashierEncashOrderService cashierEncashOrderService;
    @Autowired
    private CashierPayChannelService cashierPayChannelService;
    @Autowired
    private CashierEncashBatchService cashierEncashBatchService;
    @Autowired
    private CashierPayChannelBankService cashierPayChannelBankService;
    
    private static final int PAGE_SIZE = 500;                   // 分页大小
    
    public AlipayWapEncashTask(){}
    public AlipayWapEncashTask(CashierEncashBatch cashierEncashBatch) {
        super(cashierEncashBatch);
    }
    
    @Override
    protected void doExecute() throws Exception {
    	loggger.info("支付宝提现任务-->AlipayWapEncashTask:开始启动...");
        String batchId = cashierEncashBatch.getBatchId();
        String payChannelId = cashierEncashBatch.getPayChannelId();
        CashierPayChannel channel = cashierPayChannelService.selectByPayChannelId(payChannelId);
        if(channel==null){
        	loggger.warn(payChannelId + " -> 对应的支付渠道不存在...");
            return;
        }
        String account = channel.getChannelName();
        // TODO 加密类型需要根据平台区分，这里由于可能有多个渠道，默认用MD5
        String signType = ICashierEnumConst.CashierEncryptType.MD5.getDesc();
        String signKey = channel.getMd5Key();
        String partner = channel.getChannelUser();
        String payUrl = channel.getPayUrl();
        String notifyUrl = channel.getNotifyUrl() + "/" + channel.getPayChannelId();
        
        String fileName = getFileName();
        String filePath = Configure.getStringValue("task.encash.alipay.file.path");
        String fileNameFull = filePath+fileName;
        // 1.生成文件
        loggger.info("开始生成上传文件" + batchId);
        createFile(fileNameFull, account);
        
        // 2.请求支付宝
        loggger.info("开始请求支付宝：" + batchId);
        boolean isSuccess = AlipayPayment.bptb_pay_file(fileNameFull, partner, signType, signKey, payUrl, notifyUrl);
        if(isSuccess){
            // 3.处理完成修改批次状态为处理中
        	loggger.info("处理完成修改批次状态为处理中：" + batchId);
            cashierEncashBatchService.updateToSending(batchId, fileName);
        }
        
    }

    private void createFile(String filename, String account) {
        String batchId = cashierEncashBatch.getBatchId();
        loggger.info("createFile 接收到参数：filename="+filename+",account="+account+",batchId="+batchId);
        File file = new File(filename);
        
        List<String[]> datas = new ArrayList<String[]>();
        try {
            String dayTime = new SimpleDateFormat("yyyyMMdd").format(new Date());
            int totalCount = 0;
            double totalMoney = 0;
            datas.add(new String[]{"日期", "总金额", "总笔数", "支付宝账号(Email)"});
            datas.add(new String[]{});
            datas.add(new String[]{"商户流水号", "收款银行户名", "收款银行账号", "收款卡户银行", "收款银行所在省份", "收款银行所在市", "收款支行名称", "金额", "对公对私标志", "备注"});
            
            int pageNo = 1;
            while(true){
                List<CashierEncashOrder> orders = cashierEncashOrderService.selectBatchOrders(batchId, pageNo++, PAGE_SIZE);
                if(CollectionUtils.isEmpty(orders)){
                	loggger.info("createFile batchId="+batchId+" 没找到同批次提现订单");
                    break;
                }
                CashierPayChannelBank bank = null;
                for(CashierEncashOrder order : orders){
                    bank = cashierPayChannelBankService.getByBankCodePlatAndType(cashierEncashBatch.getPaychannelType(), order.getSellBank());
                    if(bank==null){
                    	loggger.info("createFile orderId="+order.getOrderId()+",PaychannelType="+cashierEncashBatch.getPaychannelType()+",SellBank="+order.getSellBank()+" 没找到提现的银行！");
                        continue;
                    }
                    boolean validate = cashierEncashOrderService.validateEncashSign(order);
                    if(!validate){
                        loggger.warn("msg=数据被篡改 orderId="+order.getOrderId()+" sign="+order.getSign());
                        continue;
                    }
                    datas.add(new String[]{order.getOrderId(), order.getSellName(), order.getSellAccount(), bank.getBankName(), order.getSellProvince(), order.getSellCity(), order.getSellBankBranch(), order.getMoney()+"", "2", ""});
                    totalMoney += order.getMoney();
                    totalCount++;
                }
            }
            datas.set(1, new String[]{dayTime, totalMoney+"", totalCount+"", account});
            
            File parent = new File(file.getParent());
            if(!parent.exists()){
                parent.mkdirs();
            }
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "GBK"));
            for(String[] data : datas){
                bw.write(StringUtils.join(data, ",")+"\n");
            }
            bw.close();
            loggger.info("createFile 提现文件创建完成");
        } catch (IOException e) {
            e.printStackTrace();
            loggger.error(e.getMessage());
        }catch (Exception e) {
            e.printStackTrace();
            loggger.error(e.getMessage());
        }
    }
    
    private String getFileName() {
        return cashierEncashBatch.getBankCodePlat()+"_"+cashierEncashBatch.getPaychannelType()+"_"+cashierEncashBatch.getBatchId()+".csv";
    }

}
